<?php

namespace App\Console\Commands\Fee;

use App\Enums\Fee\FeeEnum;
use App\Enums\OpenShop\InvestmentPromotion\MainProcessEnum;
use App\Enums\OpenShop\InvestmentPromotion\SignOrderEnum;
use App\Enums\OpenShop\MissionTemplateEnum;
use App\Library\Rms\RmsShopApi;
use App\Models\Common\ConfigModel;
use App\Models\Fee\FeeAnnualChangesModel;
use App\Models\Fee\FeeAnnualOrderModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\StartBusiness\OpenShopStartBusinessModel;
use App\Models\Shop\ShopModel;
use App\Remote\Rms\RmsShopRemote;
use App\Service\OpenShop\UserContractService;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;

class CreateAnnualFeeOrder extends Command
{
    const AUTOINCREMENT_REDIS_KEY = 'ANNUAL_FEE_ORDER_NO:';

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'fee:create-annual-fee-order {--shopCode=0}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '生成年费订单';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $shopCode = (int)$this->option('shopCode');

        // 如果传递了shopCode 则只生成改门店的年费订单 通过shopCode获得订单号
        $orderNos = [];
        if ($shopCode) {
            $orderNos = OpenShopSignOrderModel::query()
                ->where('shopCode', $shopCode)
                ->pluck('orderNo')
                ->toArray();
        }

        $data    = [];
        $shopIds = [];  //做幂等判断的条件

        // 结束日期Carbon类
        $endDateCarbon = Carbon::now()->addDays(90);
        $endDateMD     = $endDateCarbon->format('md');

        // 获得符合90天后截止年费截止的日期 从2018年开始
        $years = [];
        for ($i = 2018; $i <= $endDateCarbon->year; $i++) {
            $years[] = $i . $endDateMD;
        }

        OpenShopMainProcessModel::query()
            ->where('childLocationOrder', MainProcessEnum::CHILD_ORDER_0)
            ->where('startFeeTime', '>', 0)
            ->where(function ($q) use ($shopCode, $orderNos, $years) {
                if ($shopCode) {
                    $q->whereIn('orderNo', $orderNos);
                } else {
                    $q->whereIn('startFeeTime', $years);
                }
            })
            ->with(['signOrderRel', 'shopRel'])
            ->chunk(100, function ($openShopMainProcessModels) use (&$data, &$shopIds, $endDateCarbon) {
                foreach ($openShopMainProcessModels as $openShopMainProcessModel) {

                    // 过滤作废订单
                    if ($openShopMainProcessModel->signOrderRel == null || $openShopMainProcessModel->shopRel == null) {
                        continue;
                    }

                    // 过滤关闭门店
                    if ($openShopMainProcessModel->shopRel->status == ShopModel::STATUS_CLOSE) {
                        continue;
                    }

                    if ($openShopMainProcessModel->signOrderRel->status == SignOrderEnum::ORDER_STATUS_NO) {
                        continue;
                    }
                    if ($openShopMainProcessModel->signOrderRel->shopCode == 0) {
                        continue;
                    }

                    // 数字系统服务费
                    $cash   = RmsShopRemote::functionOpenDetail($openShopMainProcessModel->shopId)['functionOpenDetail'][4] ?? [];
                    $kfCash = ($cash['isOpen'] ?? false) && ($cash['serialNumber'] ?? false);

                    // 年管理费
                    $managePrice    = $openShopMainProcessModel->managePrice;
                    $contractManage = $managePrice ?: UserContractService::getManagementCostEveryYear($openShopMainProcessModel->orderNo);

                    // 根据年费收取日期获得这一阶段的年费收取时间
                    $count           = 0;
                    $nowDate         = Carbon::now()->format('Ymd');
                    $nextYearFeeDate = 0;
                    while ($nextYearFeeDate <= $nowDate) {
                        $count++;
                        $nextYearFeeDate = Carbon::createFromFormat('Ymd', $openShopMainProcessModel->startFeeTime)->addYears($count)->format('Ymd');
                    }

                    // 生成年费订单
                    $shopIds[] = $openShopMainProcessModel->shopId;
                    $data[]    = [
                        'feeOrderNo'      => self::generateFeeOrderNo(),
                        'shopId'          => $openShopMainProcessModel->shopId,
                        'shouldPayPrice'  => $kfCash ? ($contractManage + FeeEnum::FEE_SYSTEM) : $contractManage,
                        'payStatus'       => FeeAnnualOrderModel::PAY_STATUS_WAIT,
                        'manageFee'       => $contractManage,
                        'systemFee'       => $kfCash ? FeeEnum::FEE_SYSTEM : 0,
                        'endTime'         => Carbon::createFromFormat('Ymd', $nextYearFeeDate)->endOfDay()->timestamp,
                        'createdAt'       => time(),
                        'updatedAt'       => time(),
                        'startYear'       => Carbon::createFromFormat('Ymd', $nextYearFeeDate)->year,
                    ];
                }
            });

        //幂等判断
        //获取已有年费订单

        $shopInfo = (new RmsShopApi())->getShopByIds($shopIds, ['id', 'type'])['data']['shopList'] ?? [];
        $haveFeeOrder = FeeAnnualOrderModel::query()
            ->withoutGlobalScope('isDel')
            ->whereIn('shopId', $shopIds)
            ->get()
            ->map(function ($item) {
               return [
                   'shopId'  => $item->shopId,
                   'endTime' => $item->endTime,
               ];
            })->toArray();
        foreach ($data as $key => $value) {
            foreach ($haveFeeOrder as $val) {
                if ($value['shopId'] == $val['shopId'] && $value['endTime'] == $val['endTime']) {
                    unset($data[$key]);
                    break;
                }
            }
            foreach ($shopInfo as $shopType) {
                if ($value['shopId'] == $shopType['id'] && $shopType['type'] == RmsShopApi::SHOP_TYPE_DIRECT) {
                    unset($data[$key]);
                    break;
                }
            }
        }
        foreach ($data as $datum) {
            dump( '门店ID为:' . $datum['shopId'] . ' 的年费订单已生成');
        }
        $data = array_values($data);

        // 2023年第一季度年管理费减免
        [$data, $changesData] = self::firstReduce2023($data);

        [$data, $changesDataWhitelist] = self::shopSupportBy2024Whitelist($data);

        FeeAnnualOrderModel::query()->insert($data);

        if ($changesData) {
            FeeAnnualChangesModel::query()->insert($changesData);
        }
        if (!empty($changesDataWhitelist)) {
            FeeAnnualChangesModel::query()->insert($changesDataWhitelist);
        }
    }


    public static function generateFeeOrderNo()
    {
        return vsprintf("%s%s%s%s", [
            "NF",
            date("Ymd", time()),
            str_pad(
                floor(microtime(true) * 1000) - strtotime(date('Y-m-d 00:00:00'), time()) * 1000,
                8,
                "0",
                STR_PAD_LEFT
            ),
            str_pad(
                Redis::incr(self::AUTOINCREMENT_REDIS_KEY, 1) % 1000,
                3,
                "0",
                STR_PAD_LEFT
            ),
        ]);
    }

    /**
     * 2023年第一季度年管理费减免
     * @param array $data
     * @return array
     */
    public static function firstReduce2023(array $data): array
    {
        $changesData = [];
        foreach ($data as &$val) {
            if ($val['endTime'] <= strtotime("2023-12-31")) {

                // 去重 - 1家店只减免一次
                $repeat = FeeAnnualChangesModel::query()
                                               ->where('shopId', $val['shopId'])
                                               ->where('remark', '2023年第一季度年管理费减免')->count();
                if ($repeat) {
                    continue;
                }

                $shopCode = (new RmsShopApi())->getShopByIds([$val['shopId']],
                        ['shopCode'])['data']['shopList'][0]['shopCode'] ?? 0;

                if (in_array($shopCode, self::firstReduce2023ShopCodes())) {

                    $changesData[] = [
                        'shopId'        => $val['shopId'],
                        'feeOrderNo'    => $val['feeOrderNo'],
                        'field'         => 'manageFee',
                        'beforeValue'   => $beforeValue = $val['manageFee'],
                        'afterValue'    => $afterValue = (int)($val['manageFee'] / 4 * 3),
                        'createdAt'     => time(),
                        'createdByUid'  => 0,
                        'createdByName' => '系统',
                        'remark'        => '2023年第一季度年管理费减免',
                        'image'         => 'https://file.51kuafu.com/84/03/29b94f5ddb2c61a90a7679579560f1bdbf9211517aace2a018fb04d63343.jpg',
                    ];

                    $val['shouldPayPrice'] -= $beforeValue - $afterValue;
                    $val['manageFee'] -= $beforeValue - $afterValue;
                }
            }
        }

        return [$data, $changesData];
    }

    public static function firstReduce2023ShopCodes()
    {
        return [
            2553,3129,3206,1168,2169,2976,3137,1025,2484,3023,3061,3197,2991,2992,3053,3069,3067,3113,2851,3165,887,2126,3094,3215,1080,2901,2973,3010,3131,3128,3008,3157,3134,1122,1811,1899,2858,3198,2758,3209,3125,3136,3155,2814,3099,3144,3150,2612,2971,658,1636,2685,2961,3075,2739,2740,2846,3083,2792,2818,2154,3003,3032,3057,3093,3116,2856,3028,3120,2299,3153,2986,2318,2811,3014,3042,3097,2840,2982,2998,3012,2195,2975,3037,3111,2808,3030,3048,3052,3082,3086,2882,3005,3107,3199,2988,3121,1606,3050,2329,2416,3114,3024,3177,2966,3027,2911,3098,3064,2678,2935,619,2158,2899,2948,2817,3033,2681,3017,2449,2798,2864,2937,3011,2945,2956,2712,2970,2994,2839,2884,2920,2978,2983,2950,2928,2904,2865,2915,2993,278,2968,2786,2789,2852,2969,1660,1713,1832,2301,2462,2718,2733,2820,2829,2862,2964,2967,360,589,1109,1302,1735,1840,2117,2118,2249,2522,2543,2674,2679,2694,2756,2797,2805,2806,2832,2866,2890,2903,2925,2929,2933,2936,2941,2951,2955,2977,2979,2980,2985,2989,2270,2297,2796,2835,2842,2879,2939,2962,622,2128,2317,2401,2827,2831,2880,2913,2952,2841,2871,2894,2907,2949,1638,1963,2757,2891,2658,2897,2953,782,920,1182,2677,2774,2781,2821,2843,2875,2877,2922,2947,1207,2323,2661,2769,2938,2921,2849,2870,2833,902,2133,2850,2876,2926,2113,2687,2729,2772,2853,2892,1225,2838,2813,2816,2825,2874,2889,977,2114,2917,2824,2722,2783,2873,1981,2263,2272,2773,2775,2780,2800,2863,2689,2987,216,2765,2848,770,1817,2823,2803,391,660,2809,2664,2828,2881,1382,1675,2602,2801,379,2464,2793,2554,2605,2735,2802,2788,2148,2164,2662,2794,2815,2533,2771,2807,2675,2738,2751,2764,636,2537,2558,2753,237,1005,2779,1700,2705,529,2654,2748,1051,1849,2162,2557,2611,2652,2768,2777,2785,1762,2151,2180,2691,2770,2778,618,2659,2743,2719,2761,2693,2730,2713,2714,2732,2742,1856,2589,2766,607,1321,1777,2572,2741,2747,2315,2458,2571,2671,2686,2711,2725,2745,1359,1980,2275,2499,2715,2388,2608,2672,1791,2594,2665,2684,1131,2682,2136,2653,2555,2663,2668,2584,2415,2600,2633,2706,915,2542,2636,2642,2371,2592,2666,1293,2319,2634,2676,2717,2720,2737,2588,2632,791,2591,2604,2496,1562,2120,2130,2400,1015,2590,2613,2641,2669,2286,2399,2583,2607,2208,2408,2660,1050,1512,2237,2574,2495,2597,2644,1848,2440,2535,2576,2586,2599,2610,2593,1396,2420,2609,2582,1921,1901,2429,2575,2708,1841,2170,2379,2362,2488,2498,688,813,2417,2510,1195,1287,1528,2238,2538,2601,992,2560,2361,2383,2550,2551,2573,190,1961,2268,2277,2294,2325,2374,2531,2540,2596,2541,2544,2564,1971,2322,2483,2502,2545,2546,2112,2316,2457,2501,2549,1035,2213,2455,2467,2486,2515,1099,2199,2479,2523,2461,2468,2548,168,2188,2327,2138,2465,1516,2385,2442,2202,2387,2410,2500,2355,2285,1222,2228,2257,2868,2466,2333,2469,261,309,1691,2166,2259,2506,2494,2229,1259,1741,2390,2439,2478,970,2124,2380,2122,2453,802,2384,2459,2234,2298,2386,2438,2507,917,1377,1698,2382,2485,515,2480,705,2351,1513,2372,2233,2340,1299,2264,2369,2373,2357,2398,1557,1972,2247,2200,1610,2289,2450,2211,2339,2246,1532,2324,558,1503,1988,2222,2375,2418,923,952,1956,2152,2172,2262,2278,2287,2296,2335,2359,2368,2370,1102,1595,1753,1761,1990,2174,2184,2189,2256,2273,2291,2305,2306,2307,2308,2321,2352,2353,2367,661,1197,1788,1790,1885,2191,2214,2239,2251,2254,2261,2314,2376,1325,1736,1958,2196,2224,2240,2302,2356,2377,1253,2230,2284,753,2153,2290,2364,331,1749,2219,2295,1873,2260,2266,2336,1226,2279,2309,2121,2161,2163,2220,2274,2141,2330,179,1308,2349,2201,2218,2242,1970,2244,2320,2243,2304,2223,2245,1926,2150,2155,2193,2204,2207,1948,2179,2217,2209,2226,1161,1766,2280,2293,1815,1938,2175,2190,2205,2303,751,2186,2181,2210,2176,2185,2231,2276,2125,2194,1907,1895,2147,788,1969,2198,2206,1968,2177,2187,1871,2160,1261,1571,1952,2149,708,1578,1915,1992,1995,1710,2115,2156,1688,792,1835,1765,1772,1330,1806,277,2135,1932,1987,1748,2116,2119,1985,1893,370,1939,1716,1858,1900,1838,1959,258,1668,1905,1795,1863,1977,1843,951,1819,1922,1731,1960,1839,1940,1975,1993,2110,1881,1986,857,1525,1678,1792,1803,1576,1657,1853,1890,1951,2140,1697,1707,1830,1850,1946,1965,725,1728,1831,1936,1945,1955,1976,1991,1767,1917,1931,1943,809,1623,1842,1953,1989,1130,1718,1800,1919,1933,1950,1957,1209,1283,1745,1910,1920,1928,1929,1962,1783,1872,1908,1070,1757,1801,1902,1702,1833,1669,1797,823,873,1565,1798,953,1869,1916,1721,1867,1877,1776,1906,232,1752,1785,1821,1332,1677,1807,286,1176,1338,1837,1632,1705,1720,1826,1676,656,1782,1860,1999,178,1297,1361,1786,1822,1823,1845,1852,1862,1870,1879,1892,1911,1912,1001,1123,1502,1680,1708,1730,1737,1760,1769,1770,1847,1851,1857,1876,1889,332,1715,1816,1561,1751,1775,1053,1112,1085,1267,1802,799,1387,577,986,997,1640,1725,1755,1763,1789,1796,1829,820,877,1309,1563,1659,513,569,590,1750,1810,1625,1653,1756,1780,1813,982,1079,1506,1758,1809,807,812,1643,1673,1538,1656,1779,1709,738,1533,1642,933,1681,1683,1692,1759,701,1318,1392,1712,1292,101,817,819,853,1589,1661,1706,1727,832,1356,1558,1386,1703,720,1129,1650,1637,312,1629,1658,1733,595,1306,1367,1689,763,863,1609,1611,1711,1250,1645,1665,1722,826,838,1670,727,1326,1527,1103,1573,1662,1027,1223,815,1652,1107,1376,1511,1672,1679,1723,1098,1399,213,621,1682,1627,1061,1580,1388,1369,652,1608,969,1505,1596,1271,353,789,1586,659,822,1530,1600,875,1239,1593,1630,1568,1363,1379,1536,1518,1567,1288,1057,1212,1217,1393,359,1167,868,1087,1269,1323,1210,1290,667,1033,1153,1285,1175,1208,697,803,913,926,1008,1159,1160,1181,1229,1256,1277,1295,1313,1371,1378,1531,157,251,1221,1282,1300,1320,1556,867,1178,1121,1202,1157,733,1065,781,916,1257,976,1291,1281,662,883,1170,361,713,919,1003,1328,1358,787,836,1236,686,858,959,1022,1026,1093,1128,810,1312,958,1023,1031,1220,1116,1255,938,1090,650,702,967,852,1105,1315,973,1071,1115,901,1010,1101,1106,1180,990,1038,808,816,292,1091,870,1062,866,978,202,806,995,1075,798,851,1120,623,869,987,975,681,715,521,631,632,736,956,1020,1039,1082,531,925,801,267,971,762,888,1018,1011,351,598,839,1030,100,1135,639,908,985,633,703,765,939,612,757,911,880,793,859,837,579,616,651,831,961,758,501,790,690,1612,937,696,821,862,533,860,1006,268,519,592,752,767,327,773,620,761,386,576,610,768,588,772,317,575,709,711,805,373,158,378,553,737,565,538,672,707,337,655,716,729,629,637,611,692,583,675,691,609,676,625,680,503,525,578,586,591,606,613,628,605,626,597,557,323,338,365,396,567,236,390,580,520,555,333,382,362,512,536,380,272,523,291,392,229,262,357,260,371,310,325,336,231,270,293,296,311,289,300,313,288,215,239,252,308,210,259,199,131,221,223,208,3,211,167,227,205,63,116,129,201,159,197,196,13,187,160,91,166,173,177,186,192,165,121,18,98,127,128,87,58,125,22,66,65,89,103,110,115,88,112,111,93,99,97,30,37,69,57,19,10,26,1211,2271,1,5,653,506,1366,1108,1398,1118,1663,1820,1923,601,829, 1162, 3060, 3101, 3139, 3217, 3229, 3240, 2940, 3056, 3126, 3171, 3182, 3218, 3224, 1263, 2127, 2489, 2646, 2834, 3015, 3109, 3148, 3204, 3213, 2267, 2723, 3220, 2724, 2934, 1092,
        ];
    }

    /**
     * 2024 门店扶持 减免管理费
     */
    public static function shopSupportBy2024Whitelist(array $data): array
    {
        $changesData = [];
        foreach ($data as &$val) {
            // 去重 - 1家店只减免一次
            $repeat = FeeAnnualChangesModel::query()
                ->where('shopId', $val['shopId'])
                ->where('remark', '2024门店扶持')->count();
            if ($repeat) {
                continue;
            }

            if (in_array($val['shopId'], self::shopSupportShopId())) {

                $changesData[] = [
                    'shopId'        => $val['shopId'],
                    'feeOrderNo'    => $val['feeOrderNo'],
                    'field'         => 'manageFee',
                    'beforeValue'   => $beforeValue = $val['manageFee'],
                    'afterValue'    => 0,
                    'createdAt'     => time(),
                    'createdByUid'  => 0,
                    'createdByName' => '系统',
                    'remark'        => '2024门店扶持',
                    'image'         => 'https://file.51kuafu.com/b9/90/4f9ae04a8616f4a30ce674640d03bdd3b0cc2a9074d6afa6c1f234a2ad7c.jpg',
                ];

                $val['shouldPayPrice'] -= $beforeValue;
                $val['manageFee']      = 0;
            }
        }

        return [$data, $changesData];

    }

    /**
     * 扶持门店Id
     * @return int[]
     */
    public static function shopSupportShopId(): array
    {
        $value = ConfigModel::query()
            ->where('module', 'fee')
            ->where('name', 'shopSupportIn2024')
            ->value('value');


        return json_decode($value, true);
    }
}
